import React, {useState, useEffect, useMemo} from 'react';
import { to_date, loc, HandView, is_empty, ColView, loc_dt, FindBarBase, obj_int, MLink, MCmd, filter_row, filter_list, useCmd, show_mt,
    WaitUmd, uJob, Bar, uReal, cline, CkUsn, obj_str, useHigh, Btn, GridTable } from 'sui';
import { repair_task, group_task, ready_task, get_find_tm, do_md, do_add, fix_state, get_ck, load_tech, reload,
    load_col, fix_col } from './cmd';
import { PsnView } from './psn/view';
import { useAccess } from 'cache';
import { DlgState, DlgBsn } from './ctl';
import { CensusView } from './census/view';

const TaskView = () => {
    const [open_val, openVal] = useState(false);
    const [open_info, openInfo] = useState(false);
    const [open_bsn, openBsn] = useState(false);
    const [main, setMain] = useState();
    const [msg, setMsg] = useState();
    const [tech, setTech] = useState();
    const [col, setCol] = useState();
    const [opt_find, optFind] = useState();
    const [high] = useHigh(190, 100);
    const [no_acc] = useAccess();
    const umd = useCmd();

    useEffect(() => {
        load_col(setCol);
        load_tech(setTech);

        const [s, e, t] = get_find_tm();

        optFind({
            t_start: s,
            t_end: e,
            time: t,
        });

        reload(null, setMain, loc_dt(s), loc_dt(e));
    }, []);

    const getRow = useMemo(() => {
        const lst = filter_list(["sn", "tech", "state"], col);
        return filter_row(main, lst, umd.filter);
    }, [main, umd.filter, col]);

    const getCol = useMemo(() => {
        if (is_empty(col)) {
            return null;
        }

        const tmp = [
            {name: loc("l_193"), key: 'index', width: 70, frozen: true},
            {name: loc("l_238"), key: 'e_opt', width: 280, frozen: true, formatter: (props) => {
                const d = props.row;

                const btnSn = () => {
                    const sn = obj_str(d, "sn");
                    const bsn = obj_str(d, "bsn");

                    if (ready_task(sn, bsn)) {
                        return <MCmd hcmd={() => umd.pact(pact, d, "bsn")} itype="flow" disabled={no_acc("bf")} title={loc("l_881")}/>;
                    }

                    return null;
                };

                return (
                    <div className="inline-flex">
                        <MCmd hcmd={() => umd.pact(null, d, "edit")} itype="edit" disabled={no_acc("be")}/>
                        <MCmd hcmd={() => umd.pact(pact, d, "ubind")} itype="ubind" disabled={no_acc("bb")} title={loc("l_733")}/>
                        <MCmd hcmd={() => umd.pact(pact, d, "state")} itype="state" disabled={no_acc("bc")} title={loc("l_355")}/>
                        <MLink hcmd={() => umd.pact(null, d, "psn")} title={loc("l_152")} num={obj_int(d, "psn_num")}/>
                        {btnSn()}
                    </div>
                );
            }},
            {name: loc("l_229"), key: 'tp', width: 70, frozen: true, formatter: (props) => {
                const d = props.row;
                const sn = obj_str(d, "sn");
                const bsn = obj_str(d, "bsn");

                let cl = "green";
                let flag = loc("l_368");

                if (ready_task(sn, bsn)) {
                    cl = "yellow";
                    flag = loc("l_879");
                } else if (group_task(sn)) {
                    cl = "blue";
                    flag = loc("l_880");
                } else if (repair_task(sn)) {
                    cl = "orange";
                    flag = loc("l_480");
                }

                return <Bar flag={flag} cl={cl}/>;
            }},
        ];

        col.forEach(d => show_mt(tmp, d, 150));

        return tmp;
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [col]);

    const hret = () => {
        const [fs, fe] = get_find_tm();

        const s = loc_dt(fs);
        const e = loc_dt(fe);

        reload(umd.endWait, setMain, s, e);

        umd.hreturn();
    };

    if (umd.isFin("psn")) {
        return <PsnView cur={umd.cur} hreturn={hret} no_acc={no_acc}/>;
    }

    if (umd.isFin("census")) {
        return <CensusView hreturn={umd.hreturn} no_acc={no_acc} col={getCol}/>;
    }

    const hfind = (opt) => {
        umd.startWait();

        if (!opt["time"]) {
            umd.setErr(loc("l_307"));
            return;
        }

        const s = loc_dt(opt["t_start"]);
        const e = loc_dt(opt["t_end"]);

        reload(umd.endWait, setMain, s, e);
    };

    const hCol = () => {
        if (is_empty(col)) {
            return null;
        }

        const ret = [];
        col.forEach(d => {
            if (d.sn === "tech") {
                d.ctl = tech;
            }
            else if (d.sn === "state") {
                d.ctl = fix_state();
            }

            ret.push(d);
        });

        return ret;
    };

    const act = {
        "add": (v, h) => {
            const [fs, fe] = get_find_tm();

            const s = loc_dt(fs);
            const e = loc_dt(fe);

            do_add(umd, setMain, s, e, v, h);
        },
        "edit": (v, h) => {
            const [fs, fe] = get_find_tm();

            const s = loc_dt(fs);
            const e = loc_dt(fe);

            do_md(umd, setMain, s, e, v, h);
        },
        "state": (v) => {
            const [fs, fe] = get_find_tm();

            const s = loc_dt(fs);
            const e = loc_dt(fe);

            const val = {
                ...v,
                sn: obj_str(umd.cur, "sn"),
            };

            do_md(umd, setMain, s, e, val);
        },
        "bsn": (v) => {
            umd.startWait();

            const cmd = {
                line: cline(),
                task: obj_str(umd.cur, "sn"),
                ...v,
            };

            uJob(null, "pair/bsn", cmd, r => {
                const [fs, fe] = get_find_tm();

                const s = loc_dt(fs);
                const e = loc_dt(fe);

                reload(umd.endWait, setMain, s, e);
            },e => umd.setErr(), true);
        }
    };

    const pact = {
        "state": () => openVal(true),
        "ubind": () => {
            setMsg(loc("l_734"));
            openInfo(true);
        },
        "bsn": () => {
            setMsg("");
            openInfo(true);
        },
    };

    if (umd.isFin("edit") || umd.isFin("add")) {
        return <HandView umd={umd} title={loc("l_321")} act={act} col={hCol()} ck={get_ck(umd.cur, umd.value, col)}/>;
    }

    const hUbind = () => {
        const data = umd.cur;
        umd.startWait();

        uReal(null, "pair/rebind",
            {
                line: cline(),
                k: obj_str(data, "sn")
            }, r => {
                const [fs, fe] = get_find_tm();

                const s = loc_dt(fs);
                const e = loc_dt(fe);

                reload(umd.endWait, setMain, s, e);
            }, e => umd.setErr(loc("l_232")), true);
    };

    const hCmd = () => {
        if (umd.isFin("ubind")) {
            hUbind();
        } else if (umd.isFin("bsn")) {
            openBsn(true);
        }
    };

    const hreturn = () => {
        load_col(setCol);
        umd.hreturn();
    };

    if (umd.isFin("col")) {
        const list = [
            {sn: "task", name: loc("l_679"), fix: fix_col()},
        ];

        return <ColView hreturn={hreturn} title={loc("l_321")} subtitle={loc("l_221")} list={list} cur="task"/>;
    }

    const Right = () => (
        <div className="inline-flex">
            <Btn hcmd={() => umd.pact(null, null, "census")} color="teal" className="mr-4">{loc("l_832")}</Btn>
            <Btn hcmd={() => umd.pact(null, null, "col")} disabled={no_acc("ba")}>{loc("l_221")}</Btn>
            <Btn hcmd={() => umd.pact(null, {pstart: to_date(), pend: to_date()}, "add")} className="ml-3" disabled={no_acc("bd")}>{loc("l_239")}</Btn>
        </div>
    );

    const getCtl = () => {
        return {
            ctl: [
                {sn: "time", name: loc("l_308"), ctl: "IkFindDate", start: "t_start", end: "t_end"},
            ],
        };
    };

    const hclear = () => {
        const [s, e, t] = get_find_tm();

        optFind({
            t_start: s,
            t_end: e,
            time: t,
        });
    };

    return (
        <div className="flex flex-col">
            <FindBarBase left={loc("l_321")} right={<Right/>} hcmd={hfind} data={getCtl()} hclear={hclear} cur={opt_find} hfilter={umd.setFilter}/>
            <GridTable high={high} col={getCol} row={getRow} rowHeight={45} gref={umd.gref}/>
            <DlgState open={open_val} hcmd={v => umd.act(act, v)} setOpen={openVal} data={umd.cur}/>
            <DlgBsn open={open_bsn} hcmd={v => umd.act(act, v)} setOpen={openBsn} data={umd.cur}/>
            <CkUsn open={open_info} setOpen={openInfo} msg={msg} hcmd={hCmd}/>
            <WaitUmd umd={umd}/>
        </div>
    );
};

export {TaskView};
